/**
 * IPC管理模块
 * 使用函数式编程处理非认证相关的IPC通信
 * @author LYC
 * @date 2025-09-13
 */

import { ipcMain, BrowserWindow } from 'electron'
import { getNotificationManager, NotificationConfig } from '../manager/notificationManager'

/**
 * IPC处理器函数类型
 */
// 从类型定义上允许更灵活的参数和返回值类型
export type IPCHandler = (
  event: Electron.IpcMainInvokeEvent,
  ...args: any[]
) => void | Promise<void> | any

/**
 * IPC处理器映射接口
 */
export interface IPCHandlerMap {
  [channel: string]: IPCHandler
}

/**
 * DevTools相关的IPC处理器工厂
 */
export const createDevToolsHandlers = (): IPCHandlerMap => ({
  'toggle-devtools': () => {
    const focusedWindow = BrowserWindow.getFocusedWindow()
    if (!focusedWindow) return

    const isDevToolsOpened = focusedWindow.webContents.isDevToolsOpened()
    if (isDevToolsOpened) {
      focusedWindow.webContents.closeDevTools()
      console.log('DevTools closed')
    } else {
      focusedWindow.webContents.openDevTools()
      console.log('DevTools opened')
    }
  },

  'open-devtools': () => {
    const focusedWindow = BrowserWindow.getFocusedWindow()
    if (focusedWindow) {
      focusedWindow.webContents.openDevTools()
      console.log('DevTools force opened')
    }
  }
})

/**
 * 窗口相关的IPC处理器工厂
 */
export const createWindowHandlers = (): IPCHandlerMap => ({
  'minimize-window': () => {
    const focusedWindow = BrowserWindow.getFocusedWindow()
    if (focusedWindow) {
      focusedWindow.minimize()
      console.log('Window minimized')
    }
  },

  'maximize-window': () => {
    const focusedWindow = BrowserWindow.getFocusedWindow()
    if (focusedWindow) {
      if (focusedWindow.isMaximized()) {
        focusedWindow.unmaximize()
        console.log('Window unmaximized')
      } else {
        focusedWindow.maximize()
        console.log('Window maximized')
      }
    }
  },

  'close-window': () => {
    const focusedWindow = BrowserWindow.getFocusedWindow()
    if (focusedWindow) {
      focusedWindow.close()
      console.log('Window close requested')
    }
  }
})

/**
 * 应用信息相关的IPC处理器工厂
 */
export const createAppInfoHandlers = (appInfo: {
  name: string
  version: string
  description: string
  author: string
}): Record<string, () => unknown> => ({
  'get-app-info': () => appInfo,

  'get-app-version': () => appInfo.version,

  'get-platform': () => process.platform,

  'get-arch': () => process.arch
})

/**
 * 通知相关的IPC处理器工厂
 */
export const createNotificationHandlers = (): IPCHandlerMap => {
  const notificationManager = getNotificationManager()

  return {
    // 显示系统通知
    'show-notification': async (
      event: Electron.IpcMainInvokeEvent,
      config: NotificationConfig,
      id?: string
    ) => {
      try {
        const notificationId = await notificationManager.showNotification(
          config,
          {
            click: () => {
              const sender = event.sender
              if (!sender.isDestroyed()) {
                sender.send('notification-clicked', { id: id || notificationId, config })
              }
            }
          },
          id
        )
        console.log('显示通知ID:', notificationId)
        return notificationId
      } catch (error) {
        console.error('Failed to show notification:', error)
        throw error
      }
    },

    // 关闭通知
    'close-notification': (_event: Electron.IpcMainInvokeEvent, id: string) => {
      return notificationManager.closeNotification(id)
    },

    // 获取所有活动通知
    'get-active-notifications': () => {
      return notificationManager.getActiveNotificationIds()
    }
  }
}

/**
 * 注册IPC处理器的纯函数
 */
export const registerIPCHandlers = (handlers: IPCHandlerMap): void => {
  Object.entries(handlers).forEach(([channel, handler]) => {
    ipcMain.handle(channel, handler)
  })
}

/**
 * 注册IPC监听器的纯函数
 */
export const registerIPCListeners = (listeners: IPCHandlerMap): void => {
  Object.entries(listeners).forEach(([channel, handler]) => {
    ipcMain.on(channel, handler)
  })
}

/**
 * 移除IPC处理器的纯函数
 */
export const removeIPCHandlers = (channels: string[]): void => {
  channels.forEach((channel) => {
    ipcMain.removeHandler(channel)
  })
}

/**
 * 移除IPC监听器的纯函数
 */
export const removeIPCListeners = (channels: string[]): void => {
  channels.forEach((channel) => {
    ipcMain.removeAllListeners(channel)
  })
}

/**
 * 创建IPC处理器组合的高阶函数
 */
export const combineIPCHandlers = (...handlerMaps: IPCHandlerMap[]): IPCHandlerMap => {
  return handlerMaps.reduce(
    (combined, current) => ({
      ...combined,
      ...current
    }),
    {}
  )
}

/**
 * IPC管理器类（函数式风格）
 */
export class IPCManager {
  private static instance: IPCManager
  private registeredChannels: Set<string> = new Set()

  // 私有构造函数，使用单例模式
  private constructor() {
    // 初始化空集合
    this.registeredChannels = new Set<string>()
  }

  public static getInstance(): IPCManager {
    if (!IPCManager.instance) {
      IPCManager.instance = new IPCManager()
    }
    return IPCManager.instance
  }

  /**
   * 初始化所有IPC处理器
   */
  public initializeHandlers = (appInfo: {
    name: string
    version: string
    description: string
    author: string
  }): IPCManager => {
    console.log('Setting up non-auth IPC handlers...')

    // 创建处理器
    const devToolsHandlers = createDevToolsHandlers()
    const windowHandlers = createWindowHandlers()
    const appInfoHandlers = createAppInfoHandlers(appInfo)
    const notificationHandlers = createNotificationHandlers()

    // 组合所有处理器
    const allHandlers = combineIPCHandlers(
      devToolsHandlers,
      windowHandlers,
      appInfoHandlers,
      notificationHandlers
    )

    // 分离同步和异步处理器
    const syncListeners = {
      'toggle-devtools': allHandlers['toggle-devtools'],
      'open-devtools': allHandlers['open-devtools'],
      'minimize-window': allHandlers['minimize-window'],
      'maximize-window': allHandlers['maximize-window'],
      'close-window': allHandlers['close-window']
    }

    const asyncHandlers = {
      'get-app-info': allHandlers['get-app-info'],
      'get-app-version': allHandlers['get-app-version'],
      'get-platform': allHandlers['get-platform'],
      'get-arch': allHandlers['get-arch'],
      'show-notification': allHandlers['show-notification'],
      'close-notification': allHandlers['close-notification'],
      'get-active-notifications': allHandlers['get-active-notifications']
    }

    // 注册处理器
    registerIPCListeners(syncListeners)
    registerIPCHandlers(asyncHandlers)

    // 记录注册的频道
    Object.keys(allHandlers).forEach((channel) => {
      this.registeredChannels.add(channel)
    })

    console.log(`IPC handlers initialized: ${Array.from(this.registeredChannels).join(', ')}`)
    return this
  }

  /**
   * 获取已注册的频道列表
   */
  public getRegisteredChannels = (): string[] => {
    return Array.from(this.registeredChannels)
  }

  /**
   * 清理所有IPC处理器
   */
  public cleanup = (): void => {
    const channels = Array.from(this.registeredChannels)

    // 移除监听器和处理器
    removeIPCListeners(channels)
    removeIPCHandlers(channels)

    // 清空记录
    this.registeredChannels.clear()

    console.log('IPC Manager cleanup completed')
  }

  /**
   * 检查频道是否已注册
   */
  public isChannelRegistered = (channel: string): boolean => {
    return this.registeredChannels.has(channel)
  }
}

/**
 * 获取IPC管理器实例的工厂函数
 */
export const getIPCManager = (): IPCManager => {
  return IPCManager.getInstance()
}

/**
 * 创建IPC初始化器的高阶函数
 */
export const createIPCInitializer = (appInfo: {
  name: string
  version: string
  description: string
  author: string
}) => {
  const ipcManager = getIPCManager()

  return () => {
    ipcManager.initializeHandlers(appInfo)
    return ipcManager
  }
}
